package com.gxs.sample.restbeans;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;

import org.apache.commons.lang.exception.ExceptionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.gxs.ea.fileporta.data.services.FileMetaCollectionService;
import com.gxs.ea.fileportal.domain.util.ErrorResponse;
import com.gxs.ea.fileportal.domain.util.SearchParams;
import com.gxs.ea.fileportal.domain.util.SearchResults;
import com.mongodb.BasicDBObject;
import com.mongodb.DBObject;
import com.mongodb.util.JSON;

@Component
@Path("/fileMetaCollections")
public class FileMetaCollectionRestBean 
{
	@Autowired
	private FileMetaCollectionService fileMetaCollectionService;
	
	@GET
	@Path("/{personId}")
	@Produces(MediaType.APPLICATION_JSON)
	public Response getSingleTestById(@PathParam("personId") Long personId)
	{
		String person = " Person: " + personId + " exists";
		return Response.status(200).entity(person).build();
	}
	
	@POST
	@Consumes(MediaType.APPLICATION_JSON)
	@Produces(MediaType.APPLICATION_JSON)
	public Response insertMetaObject(Map<String, Object> fileMetaCollection)
	{
		BasicDBObject basicDBObject = new BasicDBObject(fileMetaCollection);
		String companyCode = (String) basicDBObject.get("companyCode");
		try
		{
			BasicDBObject savedObject = this.fileMetaCollectionService.insertDBObject(companyCode + "_files", basicDBObject);
			return Response.status(200).entity(savedObject).build();
		}
		catch(Exception e)
		{
			ErrorResponse response = new ErrorResponse();
			response.setErrorSummary("Error on saving data: " + e.getMessage());
			response.setErrorDetails(ExceptionUtils.getFullStackTrace(e));
			response.setErrorSubCode("GXS-500");
			
			//
			// We are returning 500 but in proper implementation we need to 
			// figure out if this was client data error and use 400 series or
			// 500 serires error accordingly. 
			return Response.status(500).entity(response).build();

		}
		
	}

	@POST
	@Path("/searches") // We are essentially modelling search as a secondary resource, allowing semantically correct POST operation for searches
	@Consumes(MediaType.APPLICATION_JSON)
	@Produces(MediaType.APPLICATION_JSON)
	public Response searchForFileMetaObjects(SearchParams searchParamsObject)
	{
		
		try
		{
			
			String collectionName = searchParamsObject.getCompanyCode() + "_files";
			
			long count = this.fileMetaCollectionService.countAll(collectionName, searchParamsObject.getStartIndex(), searchParamsObject.getPageSize(), searchParamsObject.getFilters(), searchParamsObject.getSearchFields());
			List<DBObject> list = this.fileMetaCollectionService.listAll(collectionName, searchParamsObject.getStartIndex(), searchParamsObject.getPageSize(), searchParamsObject.getSortField(), searchParamsObject.getSortOrder(),searchParamsObject.getFilters(), searchParamsObject.getSearchFields());
			
			List<Map> listOfJson = new ArrayList<Map>();
			
			for(DBObject dbo : list)
			{
				Map m = dbo.toMap();
				listOfJson.add(m);
			}

			SearchResults results = new SearchResults();
			results.setPageSize(searchParamsObject.getPageSize());
			results.setStartIndex(searchParamsObject.getStartIndex());
			results.setTotalCount(count);
			results.setSearchResults(listOfJson);
			
			return Response.status(200).entity(results).build();
			
		}
		catch(Exception e)
		{
			ErrorResponse response = new ErrorResponse();
			response.setErrorSummary("Error on searching data: " + e.getMessage());
			response.setErrorDetails(ExceptionUtils.getFullStackTrace(e));
			response.setErrorSubCode("GXS-500");
			
			//
			// We are returning 500 but in proper implementation we need to 
			// figure out if this was client data error and use 400 series or
			// 500 serires error accordingly. 
			return Response.status(500).entity(response).build();

		}
		
	}

	
	public FileMetaCollectionService getFileMetaCollectionService() {
		return fileMetaCollectionService;
	}

	public void setFileMetaCollectionService(
			FileMetaCollectionService fileMetaCollectionService) {
		this.fileMetaCollectionService = fileMetaCollectionService;
	}


}
